machine library and ESP32 reference
machine
- functions related to the hardware
The machine
module contains specific functions related to the hardware on a particular board.
Most functions in this module allow to achieve direct and unrestricted access to and control of hardware blocks on a system (like CPU, timers, buses, etc.).
Used incorrectly, this can lead to malfunction, lockups, crashes of your board, and in extreme cases, hardware damage.
A note of callbacks used by functions and class methods of machine
module:
all these callbacks should be considered as executing in an interrupt context.
This is true for both physical devices with IDs >= 0 and "virtual" devices with negative IDs like -1 (these "virtual" devices are still thin shims on top of real hardware and real hardware interrupts).
See Writing interrupt handlers.
-- Reset related functions
machine.
reset
()
- Resets the device in a manner similar to pushing the external RESET
button.
machine.
soft_reset
()
- Performs a soft reset of the interpreter, deleting all Python objects and resetting the Python heap.
It tries to retain the method by which the user is connected to the MicroPython REPL (eg serial, USB, Wifi).
machine.
reset_cause
()
- Get the reset cause.
See constants for the possible return values.
-- Interrupt related functions
machine.
disable_irq
()
- Disable interrupt requests.
Returns the previous IRQ state which should be considered an opaque value.
This return value should be passed to the
enable_irq()
function to restore interrupts to their original state, before disable_irq()
was called.
machine.
enable_irq
(state)
- Re-enable interrupt requests.
The state parameter should be the value that was returned from the most recent call to the
disable_irq()
function.
-- Power related functions
machine.
freq
()
- Returns CPU frequency in hertz.
machine.
idle
()
- Gates the clock to the CPU, useful to reduce power consumption at any time during short or long periods.
Peripherals continue working and execution resumes as soon as any interrupt is triggered (on many ports this includes system timer interrupt occurring at regular intervals on the order of millisecond).
machine.
sleep
()
-
Note
This function is deprecated, use
lightsleep()
instead with no arguments.
machine.
lightsleep
([time_ms])-
machine.
deepsleep
([time_ms])
- Stops execution in an attempt to enter a low power state.
If time_ms is specified then this will be the maximum time in milliseconds that the sleep will last for.
Otherwise the sleep can last indefinitely.
With or without a timout, execution may resume at any time if there are events that require processing.
Such events, or wake sources, should be configured before sleeping, like
Pin
change or RTC
timeout.
The precise behaviour and power-saving capabilities of lightsleep and deepsleep is highly dependent on the underlying hardware, but the general properties are:
- A lightsleep has full RAM and state retention.
Upon wake execution is resumed from the point where the sleep was requested, with all subsystems operational.
- A deepsleep may not retain RAM or any other state of the system (for example peripherals or network interfaces).
Upon wake execution is resumed from the main script, similar to a hard or power-on reset.
The
reset_cause()
function will return machine.DEEPSLEEP
and this can be used to distinguish a deepsleep wake from other resets.
machine.
wake_reason
()
- Get the wake reason.
See constants for the possible return values.
Availability: ESP32, WiPy.
-- Miscellaneous functions
machine.
unique_id
()
- Returns a byte string with a unique identifier of a board/SoC.
It will vary from a board/SoC instance to another, if underlying hardware allows.
Length varies by hardware (so use substring of a full value if you expect a short ID).
In some MicroPython ports, ID corresponds to the network MAC address.
machine.
time_pulse_us
(pin, pulse_level, timeout_us=1000000, /)
- Time a pulse on the given pin, and return the duration of the pulse in microseconds.
The pulse_level argument should be 0 to time a low pulse
or 1 to time a high pulse.
If the current input value of the pin is different to pulse_level,
the function first (*) waits until the pin input becomes equal to pulse_level, then (**) times the duration that the pin is equal to pulse_level.
If the pin is already equal to pulse_level then timing starts straight away.
The function will return -2 if there was timeout waiting for condition marked (*) above, and -1 if there was timeout during the main measurement, marked (**) above.
The timeout is the same for both cases and given by timeout_us (which is in microseconds).
machine.
rng
()
- Return a 24-bit software generated random number.
Availability: WiPy.
Constants
machine.
IDLE
-
machine.
SLEEP
-
machine.
DEEPSLEEP
- IRQ wake values.
machine.
PWRON_RESET
-
machine.
HARD_RESET
-
machine.
WDT_RESET
-
machine.
DEEPSLEEP_RESET
-
machine.
SOFT_RESET
- Reset causes.
machine.
WLAN_WAKE
-
machine.
PIN_WAKE
-
machine.
RTC_WAKE
- Wake-up reasons.
-- Classes
class Pin - control I/O pins
class Signal - control and sense external I/O devices
class ADC - analog to digital conversion
class UART - duplex serial communication bus
class SPI - a Serial Peripheral Interface bus protocol (master side)
class I2C - a two-wire serial protocol
class RTC - real time clock
class Timer - control hardware timers
class WDT - watchdog timer
class SD - secure digital memory card (cc3200 port only)
class SDCard - secure digital memory card
class Pin - control I/O pins
A pin object is used to control I/O pins (also known as GPIO - general-purpose
input/output).
Pin objects are commonly associated with a physical pin that can drive an output voltage and read input voltages.
The pin class has methods to set the mode of the pin (IN, OUT, etc) and methods to get and set the digital logic level.
For analog control of a pin, see the ADC
class.
A pin object is constructed by using an identifier which unambiguously
specifies a certain I/O pin.
The allowed forms of the identifier and the physical pin that the identifier maps to are port-specific.
Possibilities for the identifier are an integer, a string or a tuple with port and pin number.
Usage Model:
from machine import Pin
# create an output pin on pin #0
p0 = Pin(0, Pin.OUT)
# set the value low then high
p0.value(0)
p0.value(1)
# create an input pin on pin #2, with a pull up resistor
p2 = Pin(2, Pin.IN, Pin.PULL_UP)
# read and print the pin value
print(p2.value())
# reconfigure pin #0 in input mode
p0.mode(p0.IN)
# configure an irq callback
p0.irq(lambda p:print(p))
Constructors
- class
machine.
Pin
(id, mode=-1, pull=-1, *, value, drive, alt)
- Access the pin peripheral (GPIO pin) associated with the given
id
.
If additional arguments are given in the constructor then they are used to initialise the pin.
Any settings that are not specified will remain in their previous state.
The arguments are:
id
is mandatory and can be an arbitrary object.
Among possible value types are: int (an internal Pin identifier), str (a Pin name), and tuple (pair of [port, pin]).
mode
specifies the pin mode, which can be one of:
Pin.IN
- Pin is configured for input.
If viewed as an output the pin is in high-impedance state.
Pin.OUT
- Pin is configured for (normal) output.
Pin.OPEN_DRAIN
- Pin is configured for open-drain output.
Open-drain output works in the following way: if the output value is set to 0 the pin is active at a low level; if the output value is 1 the pin is in a high-impedance state.
Not all ports implement this mode, or some might only on certain pins.
Pin.ALT
- Pin is configured to perform an alternative function, which is port specific.
For a pin configured in such a way any other Pin methods
(except Pin.init()
) are not applicable (calling them will lead to undefined, or a hardware-specific, result).
Not all ports implement this mode.
Pin.ALT_OPEN_DRAIN
- The Same as Pin.ALT
, but the pin is configured as open-drain.
Not all ports implement this mode.
pull
specifies if the pin has a (weak) pull resistor attached, and can be one of:
None
- No pull up or down resistor.
Pin.PULL_UP
- Pull up resistor enabled.
Pin.PULL_DOWN
- Pull down resistor enabled.
value
is valid only for Pin.OUT and Pin.OPEN_DRAIN modes and specifies initial output pin value if given, otherwise the state of the pin peripheral remains unchanged.
drive
specifies the output power of the pin and can be one of: Pin.LOW_POWER
, Pin.MED_POWER
or Pin.HIGH_POWER
.
The actual current driving capabilities are port dependent.
Not all ports implement this argument.
alt
specifies an alternate function for the pin and the values it can take are port dependent.
This argument is valid only for Pin.ALT
and Pin.ALT_OPEN_DRAIN
modes.
It may be used when a pin supports more than one alternate function.
If only one pin alternate function is supported the this argument is not required.
Not all ports implement this argument.
As specified above, the Pin class allows to set an alternate function for a particular pin, but it does not specify any further operations on such a pin.
Pins configured in alternate-function mode are usually not used as GPIO but are instead driven by other hardware peripherals.
The only operation supported on such a pin is re-initialising,
by calling the constructor or Pin.init()
method.
If a pin that is configured in alternate-function mode is re-initialised with Pin.IN
, Pin.OUT
, or Pin.OPEN_DRAIN
, the alternate function will be removed from the pin.
Methods
Pin.
init
(mode=-1, pull=-1, *, value, drive, alt)
- Re-initialise the pin using the given parameters.
Only those arguments that are specified will be set.
The rest of the pin peripheral state will remain unchanged.
See the constructor documentation for details of the arguments.
Returns
None
.
Pin.
value
([x])
- This method allows to set and get the value of the pin, depending on whether the argument
x
is supplied or not.
If the argument is omitted then this method gets the digital logic level of
the pin, returning 0 or 1 corresponding to low and high voltage signals
respectively.
The behaviour of this method depends on the mode of the pin:
Pin.IN
- The method returns the actual input value currently present on the pin.
Pin.OUT
- The behaviour and return value of the method is undefined.
Pin.OPEN_DRAIN
- If the pin is in state ‘0’ then the behaviour and return value of the method is undefined.
Otherwise, if the pin is in state ‘1’, the method returns the actual input value currently present on the pin.
If the argument is supplied then this method sets the digital logic level of
the pin.
The argument x
can be anything that converts to a boolean.
If it converts to True
, the pin is set to state ‘1’, otherwise it is set to state ‘0’.
The behaviour of this method depends on the mode of the pin:
Pin.IN
- The value is stored in the output buffer for the pin.
The pin state does not change, it remains in the high-impedance state.
The stored value will become active on the pin as soon as it is changed to
Pin.OUT
or Pin.OPEN_DRAIN
mode.
Pin.OUT
- The output buffer is set to the given value immediately.
Pin.OPEN_DRAIN
- If the value is ‘0’ the pin is set to a low voltage state.
Otherwise the pin is set to high-impedance state.
When setting the value this method returns None
.
Pin.
__call__
([x])
- Pin objects are callable.
The call method provides a (fast) shortcut to set and get the value of the pin.
It is equivalent to Pin.value([x]).
See
Pin.value()
for more details.
Pin.
on
()
- Set pin to "1" output level.
Pin.
off
()
- Set pin to "0" output level.
Pin.
mode
([mode])
- Get or set the pin mode.
See the constructor documentation for details of the
mode
argument.
Pin.
pull
([pull])
- Get or set the pin pull state.
See the constructor documentation for details of the
pull
argument.
Pin.
drive
([drive])
- Get or set the pin drive strength.
See the constructor documentation for details of the
drive
argument.
Not all ports implement this method.
Availability: WiPy.
Pin.
irq
(handler=None, trigger=(Pin.IRQ_FALLING | Pin.IRQ_RISING), *, priority=1, wake=None, hard=False)
- Configure an interrupt handler to be called when the trigger source of the pin is active.
If the pin mode is
Pin.IN
then the trigger source is
the external value on the pin.
If the pin mode is Pin.OUT
then the trigger source is the output buffer of the pin.
Otherwise, if the pin mode is Pin.OPEN_DRAIN
then the trigger source is the output buffer for state ‘0’ and the external pin value for state ‘1’.
The arguments are:
handler
is an optional function to be called when the interrupt triggers.
The handler must take exactly one argument which is the Pin
instance.
trigger
configures the event which can generate an interrupt.
Possible values are:
Pin.IRQ_FALLING
interrupt on falling edge.
Pin.IRQ_RISING
interrupt on rising edge.
Pin.IRQ_LOW_LEVEL
interrupt on low level.
Pin.IRQ_HIGH_LEVEL
interrupt on high level.
These values can be OR’ed together to trigger on multiple events.
priority
sets the priority level of the interrupt.
The values it can take are port-specific, but higher values always represent higher priorities.
wake
selects the power mode in which this interrupt can wake up the system.
It can be machine.IDLE
, machine.SLEEP
or machine.DEEPSLEEP
.
These values can also be OR’ed together to make a pin generate interrupts in more than one power mode.
hard
if true a hardware interrupt is used.
This reduces the delay between the pin change and the handler being called.
Hard interrupt handlers may not allocate memory; see Writing interrupt handlers.
This method returns a callback object.
Constants
The following constants are used to configure the pin objects.
Note that
not all constants are available on all ports.
Pin.
IN
-
Pin.
OUT
-
Pin.
OPEN_DRAIN
-
Pin.
ALT
-
Pin.
ALT_OPEN_DRAIN
- Selects the pin mode.
Pin.
PULL_UP
-
Pin.
PULL_DOWN
-
Pin.
PULL_HOLD
- Selects whether there is a pull up/down resistor.
Use the value
None
for no pull.
Pin.
LOW_POWER
-
Pin.
MED_POWER
-
Pin.
HIGH_POWER
- Selects the pin drive strength.
Pin.
IRQ_FALLING
-
Pin.
IRQ_RISING
-
Pin.
IRQ_LOW_LEVEL
-
Pin.
IRQ_HIGH_LEVEL
- Selects the IRQ trigger type.
class Signal - control and sense external I/O devices
The Signal class is a simple extension of the Pin
class.
Unlike Pin, which
can be only in "absolute" 0 and 1 states, a Signal can be in "asserted"
(on) or "deasserted" (off) states, while being inverted (active-low) or
not.
In other words, it adds logical inversion support to Pin functionality.
While this may seem a simple addition, it is exactly what is needed to
support wide array of simple digital devices in a way portable across
different boards, which is one of the major MicroPython goals.
Regardless
of whether different users have an active-high or active-low LED, a normally
open or normally closed relay - you can develop a single, nicely looking
application which works with each of them, and capture hardware
configuration differences in few lines in the config file of your app.
Example:
from machine import Pin, Signal
# Suppose you have an active-high LED on pin 0
led1_pin = Pin(0, Pin.OUT)
# ...
and active-low LED on pin 1
led2_pin = Pin(1, Pin.OUT)
# Now to light up both of them using Pin class, you'll need to set
# them to different values
led1_pin.value(1)
led2_pin.value(0)
# Signal class allows to abstract away active-high/active-low
# difference
led1 = Signal(led1_pin, invert=False)
led2 = Signal(led2_pin, invert=True)
# Now lighting up them looks the same
led1.value(1)
led2.value(1)
# Even better:
led1.on()
led2.on()
Following is the guide when Signal vs Pin should be used:
Use Signal: If you want to control a simple on/off (including software
PWM!) devices like LEDs, multi-segment indicators, relays, buzzers, or
read simple binary sensors, like normally open or normally closed buttons,
pulled high or low, Reed switches, moisture/flame detectors, etc.
etc.
Summing up, if you have a real physical device/sensor requiring GPIO
access, you likely should use a Signal.
Use Pin: If you implement a higher-level protocol or bus to communicate
with more complex devices.
The split between Pin and Signal come from the usecases above and the
architecture of MicroPython: Pin offers the lowest overhead, which may
be important when bit-banging protocols.
But Signal adds additional
flexibility on top of Pin, at the cost of minor overhead (much smaller
than if you implemented active-high vs active-low device differences in
Python manually!).
Also, Pin is a low-level object which needs to be
implemented for each support board, while Signal is a high-level object
which comes for free once Pin is implemented.
If in doubt, give the Signal a try! Once again, it is offered to save
developers from the need to handle unexciting differences like active-low
vs active-high signals, and allow other users to share and enjoy your
application, instead of being frustrated by the fact that it doesn’t
work for them simply because their LEDs or relays are wired in a slightly
different way.
Constructors
- class
machine.
Signal
(pin_obj, invert=False) -
class
machine.
Signal
(pin_arguments..., *, invert=False)
- Create a Signal object.
There’re two ways to create it:
- By wrapping existing Pin object - universal method which works for
any board.
- By passing required Pin parameters directly to Signal constructor,
skipping the need to create intermediate Pin object.
Available on
many, but not all boards.
The arguments are:
pin_obj
is existing Pin object.
pin_arguments
are the same arguments as can be passed to Pin constructor.
invert
- if True, the signal will be inverted (active low).
Methods
Signal.
value
([x])
- This method allows to set and get the value of the signal, depending on whether
the argument
x
is supplied or not.
If the argument is omitted then this method gets the signal level, 1 meaning
signal is asserted (active) and 0 - signal inactive.
If the argument is supplied then this method sets the signal level.
The
argument x
can be anything that converts to a boolean.
If it converts
to True
, the signal is active, otherwise it is inactive.
Correspondence between signal being active and actual logic level on the
underlying pin depends on whether signal is inverted (active-low) or not.
For non-inverted signal, active status corresponds to logical 1, inactive -
to logical 0.
For inverted/active-low signal, active status corresponds
to logical 0, while inactive - to logical 1.
Signal.
on
()
- Activate signal.
Signal.
off
()
- Deactivate signal.
class ADC - analog to digital conversion
The ADC class provides an interface to analog-to-digital convertors, and
represents a single endpoint that can sample a continuous voltage and
convert it to a discretised value.
Example usage:
import machine
adc = machine.ADC(pin) # create an ADC object acting on a pin
val = adc.read_u16() # read a raw analog value in the range 0-65535
Constructors
- class
machine.
ADC
(id)
- Access the ADC associated with a source identified by id.
This
id may be an integer (usually specifying a channel number), a
Pin object, or other value supported by the
underlying machine.
Methods
ADC.
read_u16
()
- Take an analog reading and return an integer in the range 0-65535.
The return value represents the raw reading taken by the ADC, scaled
such that the minimum value is 0 and the maximum value is 65535.
class UART - duplex serial communication bus
UART implements the standard UART/USART duplex serial communications protocol.
At
the physical level it consists of 2 lines: RX and TX.
The unit of communication
is a character (not to be confused with a string character) which can be 8 or 9
bits wide.
UART objects can be created and initialised using:
from machine import UART
uart = UART(1, 9600) # init with given baudrate
uart.init(9600, bits=8, parity=None, stop=1) # init with given parameters
Supported parameters differ on a board:
Pyboard: Bits can be 7, 8 or 9.
Stop can be 1 or 2.
With parity=None,
only 8 and 9 bits are supported.
With parity enabled, only 7 and 8 bits
are supported.
WiPy/CC3200: Bits can be 5, 6, 7, 8.
Stop can be 1 or 2.
A UART object acts like a stream
object and reading and writing is done
using the standard stream methods:
uart.read(10) # read 10 characters, returns a bytes object
uart.read() # read all available characters
uart.readline() # read a line
uart.readinto(buf) # read and store into the given buffer
uart.write('abc') # write the 3 characters
Constructors
- class
machine.
UART
(id, ...)
- Construct a UART object of the given id.
Methods
UART.
init
(baudrate=9600, bits=8, parity=None, stop=1, *, ...)
- Initialise the UART bus with the given parameters:
- baudrate is the clock rate.
- bits is the number of bits per character, 7, 8 or 9.
- parity is the parity,
None
, 0 (even) or 1 (odd).
- stop is the number of stop bits, 1 or 2.
Additional keyword-only parameters that may be supported by a port are:
- tx specifies the TX pin to use.
- rx specifies the RX pin to use.
- txbuf specifies the length in characters of the TX buffer.
- rxbuf specifies the length in characters of the RX buffer.
- timeout specifies the time to wait for the first character (in ms).
- timeout_char specifies the time to wait between characters (in ms).
- invert specifies which lines to invert.
On the WiPy only the following keyword-only parameter is supported:
- pins is a 4 or 2 item list indicating the TX, RX, RTS and CTS pins (in that order).
Any of the pins can be None if one wants the UART to operate with limited functionality.
If the RTS pin is given the the RX pin must be given as well.
The same applies to CTS.
When no pins are given, then the default set of TX and RX pins is taken, and hardware
flow control will be disabled.
If pins is
None
, no pin assignment will be made.
UART.
deinit
()
- Turn off the UART bus.
UART.
any
()
- Returns an integer counting the number of characters that can be read without
blocking.
It will return 0 if there are no characters available and a positive
number if there are characters.
The method may return 1 even if there is more
than one character available for reading.
For more sophisticated querying of available characters use select.poll:
poll = select.poll()
poll.register(uart, select.POLLIN)
poll.poll(timeout)
UART.
read
([nbytes])
- Read characters.
If
nbytes
is specified then read at most that many bytes,
otherwise read as much data as possible.
It may return sooner if a timeout
is reached.
The timeout is configurable in the constructor.
Return value: a bytes object containing the bytes read in.
Returns None
on timeout.
UART.
readinto
(buf[, nbytes])
- Read bytes into the
buf
.
If nbytes
is specified then read at most
that many bytes.
Otherwise, read at most len(buf)
bytes.
It may return sooner if a timeout
is reached.
The timeout is configurable in the constructor.
Return value: number of bytes read and stored into buf
or None
on
timeout.
UART.
readline
()
- Read a line, ending in a newline character.
It may return sooner if a timeout
is reached.
The timeout is configurable in the constructor.
Return value: the line read or
None
on timeout.
UART.
write
(buf)
- Write the buffer of bytes to the bus.
Return value: number of bytes written or
None
on timeout.
UART.
sendbreak
()
- Send a break condition on the bus.
This drives the bus low for a duration
longer than required for a normal transmission of a character.
UART.
irq
(trigger, priority=1, handler=None, wake=machine.IDLE)
- Create a callback to be triggered when data is received on the UART.
- trigger can only be
UART.RX_ANY
- priority level of the interrupt.
Can take values in the range 1-7.
Higher values represent higher priorities.
- handler an optional function to be called when new characters arrive.
- wake can only be
machine.IDLE
.
Note
The handler will be called whenever any of the following two conditions are met:
- 8 new characters have been received.
- At least 1 new character is waiting in the Rx buffer and the Rx line has been
silent for the duration of 1 complete frame.
This means that when the handler function is called there will be between 1 to 8
characters waiting.
Returns an irq object.
Availability: WiPy.
Constants
UART.
RX_ANY
- IRQ trigger sources
Availability: WiPy.
class SPI - a Serial Peripheral Interface bus protocol (master side)
SPI is a synchronous serial protocol that is driven by a master.
At the
physical level, a bus consists of 3 lines: SCK, MOSI, MISO.
Multiple devices
can share the same bus.
Each device should have a separate, 4th signal,
SS (Slave Select), to select a particular device on a bus with which
communication takes place.
Management of an SS signal should happen in
user code (via machine.Pin class).
Constructors
- class
machine.
SPI
(id, ...)
- Construct an SPI object on the given bus,
id
.
Values of id
depend
on a particular port and its hardware.
Values 0, 1, etc.
are commonly used
to select hardware SPI block #0, #1, etc.
Value -1 can be used for
bitbanging (software) implementation of SPI (if supported by a port).
With no additional parameters, the SPI object is created but not
initialised (it has the settings from the last initialisation of
the bus, if any).
If extra arguments are given, the bus is initialised.
See init
for parameters of initialisation.
Methods
SPI.
init
(baudrate=1000000, *, polarity=0, phase=0, bits=8, firstbit=SPI.MSB, sck=None, mosi=None, miso=None, pins=(SCK, MOSI, MISO))
- Initialise the SPI bus with the given parameters:
baudrate
is the SCK clock rate.
polarity
can be 0 or 1, and is the level the idle clock line sits at.
phase
can be 0 or 1 to sample data on the first or second clock edge
respectively.
bits
is the width in bits of each transfer.
Only 8 is guaranteed to be supported by all hardware.
firstbit
can be SPI.MSB
or SPI.LSB
.
sck
, mosi
, miso
are pins (machine.Pin) objects to use for bus signals.
For most
hardware SPI blocks (as selected by id
parameter to the constructor), pins are fixed
and cannot be changed.
In some cases, hardware blocks allow 2-3 alternative pin sets for
a hardware SPI block.
Arbitrary pin assignments are possible only for a bitbanging SPI driver
(id
= -1).
pins
- WiPy port doesn’t sck
, mosi
, miso
arguments, and instead allows to
specify them as a tuple of pins
parameter.
In the case of hardware SPI the actual clock frequency may be lower than the
requested baudrate.
This is dependant on the platform hardware.
The actual
rate may be determined by printing the SPI object.
SPI.
deinit
()
- Turn off the SPI bus.
SPI.
read
(nbytes, write=0x00)
- Read a number of bytes specified by
nbytes
while continuously writing
the single byte given by write
.
Returns a bytes
object with the data that was read.
SPI.
readinto
(buf, write=0x00)
- Read into the buffer specified by
buf
while continuously writing the
single byte given by write
.
Returns None
.
Note: on WiPy this function returns the number of bytes read.
SPI.
write
(buf)
- Write the bytes contained in
buf
.
Returns None
.
Note: on WiPy this function returns the number of bytes written.
SPI.
write_readinto
(write_buf, read_buf)
- Write the bytes from
write_buf
while reading into read_buf
.
The
buffers can be the same or different, but both buffers must have the
same length.
Returns None
.
Note: on WiPy this function returns the number of bytes written.
Constants
SPI.
MASTER
- for initialising the SPI bus to master; this is only used for the WiPy
SPI.
MSB
- set the first bit to be the most significant bit
SPI.
LSB
- set the first bit to be the least significant bit
class I2C - a two-wire serial protocol
I2C is a two-wire protocol for communicating between devices.
At the physical
level it consists of 2 wires: SCL and SDA, the clock and data lines respectively.
I2C objects are created attached to a specific bus.
They can be initialised
when created, or initialised later on.
Printing the I2C object gives you information about its configuration.
Example usage:
from machine import I2C
i2c = I2C(freq=400000) # create I2C peripheral at frequency of 400kHz
# depending on the port, extra parameters may be required
# to select the peripheral and/or pins to use
i2c.scan() # scan for slaves, returning a list of 7-bit addresses
i2c.writeto(42, b'123') # write 3 bytes to slave with 7-bit address 42
i2c.readfrom(42, 4) # read 4 bytes from slave with 7-bit address 42
i2c.readfrom_mem(42, 8, 3) # read 3 bytes from memory of slave 42,
# starting at memory-address 8 in the slave
i2c.writeto_mem(42, 2, b'\x10') # write 1 byte to memory of slave 42
# starting at address 2 in the slave
Constructors
- class
machine.
I2C
(id=-1, *, scl, sda, freq=400000)
- Construct and return a new I2C object using the following parameters:
- id identifies a particular I2C peripheral.
The default
value of -1 selects a software implementation of I2C which can
work (in most cases) with arbitrary pins for SCL and SDA.
If id is -1 then scl and sda must be specified.
Other
allowed values for id depend on the particular port/board,
and specifying scl and sda may or may not be required or
allowed in this case.
- scl should be a pin object specifying the pin to use for SCL.
- sda should be a pin object specifying the pin to use for SDA.
- freq should be an integer which sets the maximum frequency
for SCL.
-- General Methods
I2C.
init
(scl, sda, *, freq=400000)
- Initialise the I2C bus with the given arguments:
- scl is a pin object for the SCL line
- sda is a pin object for the SDA line
- freq is the SCL clock rate
I2C.
deinit
()
- Turn off the I2C bus.
Availability: WiPy.
I2C.
scan
()
- Scan all I2C addresses between 0x08 and 0x77 inclusive and return a list of
those that respond.
A device responds if it pulls the SDA line low after
its address (including a write bit) is sent on the bus.
-- Primitive I2C operations
The following methods implement the primitive I2C master bus operations and can
be combined to make any I2C transaction.
They are provided if you need more
control over the bus, otherwise the standard methods (see below) can be used.
These methods are available on software I2C only.
I2C.
start
()
- Generate a START condition on the bus (SDA transitions to low while SCL is high).
I2C.
stop
()
- Generate a STOP condition on the bus (SDA transitions to high while SCL is high).
I2C.
readinto
(buf, nack=True, /)
- Reads bytes from the bus and stores them into buf.
The number of bytes
read is the length of buf.
An ACK will be sent on the bus after
receiving all but the last byte.
After the last byte is received, if nack
is true then a NACK will be sent, otherwise an ACK will be sent (and in this
case the slave assumes more bytes are going to be read in a later call).
I2C.
write
(buf)
- Write the bytes from buf to the bus.
Checks that an ACK is received
after each byte and stops transmitting the remaining bytes if a NACK is
received.
The function returns the number of ACKs that were received.
-- Standard bus operations
The following methods implement the standard I2C master read and write
operations that target a given slave device.
I2C.
readfrom
(addr, nbytes, stop=True, /)
- Read nbytes from the slave specified by addr.
If stop is true then a STOP condition is generated at the end of the transfer.
Returns a
bytes
object with the data read.
I2C.
readfrom_into
(addr, buf, stop=True, /)
- Read into buf from the slave specified by addr.
The number of bytes read will be the length of buf.
If stop is true then a STOP condition is generated at the end of the transfer.
The method returns
None
.
I2C.
writeto
(addr, buf, stop=True, /)
- Write the bytes from buf to the slave specified by addr.
If a
NACK is received following the write of a byte from buf then the
remaining bytes are not sent.
If stop is true then a STOP condition is
generated at the end of the transfer, even if a NACK is received.
The function returns the number of ACKs that were received.
I2C.
writevto
(addr, vector, stop=True, /)
- Write the bytes contained in vector to the slave specified by addr.
vector should be a tuple or list of objects with the buffer protocol.
The addr is sent once and then the bytes from each object in vector
are written out sequentially.
The objects in vector may be zero bytes
in length in which case they don’t contribute to the output.
If a NACK is received following the write of a byte from one of the
objects in vector then the remaining bytes, and any remaining objects,
are not sent.
If stop is true then a STOP condition is generated at
the end of the transfer, even if a NACK is received.
The function
returns the number of ACKs that were received.
-- Memory operations
Some I2C devices act as a memory device (or set of registers) that can be read
from and written to.
In this case there are two addresses associated with an
I2C transaction: the slave address and the memory address.
The following
methods are convenience functions to communicate with such devices.
I2C.
readfrom_mem
(addr, memaddr, nbytes, *, addrsize=8)
- Read nbytes from the slave specified by addr starting from the memory
address specified by memaddr.
The argument addrsize specifies the address size in bits.
Returns a
bytes
object with the data read.
I2C.
readfrom_mem_into
(addr, memaddr, buf, *, addrsize=8)
- Read into buf from the slave specified by addr starting from the
memory address specified by memaddr.
The number of bytes read is the
length of buf.
The argument addrsize specifies the address size in bits (on ESP8266
this argument is not recognised and the address size is always 8 bits).
The method returns
None
.
I2C.
writeto_mem
(addr, memaddr, buf, *, addrsize=8)
- Write buf to the slave specified by addr starting from the
memory address specified by memaddr.
The argument addrsize specifies the address size in bits (on ESP8266
this argument is not recognised and the address size is always 8 bits).
The method returns
None
.
class RTC - real time clock
The RTC is and independent clock that keeps track of the date
and time.
Example usage:
rtc = machine.RTC()
rtc.init((2014, 5, 1, 4, 13, 0, 0, 0))
print(rtc.now())
Constructors
- class
machine.
RTC
(id=0, ...)
- Create an RTC object.
See init for parameters of initialization.
Methods
RTC.
init
(datetime)
- Initialise the RTC.
Datetime is a tuple of the form:
(year, month, day[, hour[, minute[, second[, microsecond[, tzinfo]]]]])
RTC.
now
()
- Get get the current datetime tuple.
RTC.
deinit
()
- Resets the RTC to the time of January 1, 2015 and starts running it again.
RTC.
alarm
(id, time, *, repeat=False)
- Set the RTC alarm.
Time might be either a millisecond value to program the alarm to
current time + time_in_ms in the future, or a datetimetuple.
If the time passed is in
milliseconds, repeat can be set to
True
to make the alarm periodic.
RTC.
alarm_left
(alarm_id=0)
- Get the number of milliseconds left before the alarm expires.
RTC.
cancel
(alarm_id=0)
- Cancel a running alarm.
RTC.
irq
(*, trigger, handler=None, wake=machine.IDLE)
- Create an irq object triggered by a real time clock alarm.
trigger
must be RTC.ALARM0
handler
is the function to be called when the callback is triggered.
wake
specifies the sleep mode from where this interrupt can wake
up the system.
Constants
RTC.
ALARM0
- irq trigger source
class Timer - control hardware timers
Hardware timers deal with timing of periods and events.
Timers are perhaps
the most flexible and heterogeneous kind of hardware in MCUs and SoCs,
differently greatly from a model to a model.
MicroPython’s Timer class
defines a baseline operation of executing a callback with a given period
(or once after some delay), and allow specific boards to define more
non-standard behavior (which thus won’t be portable to other boards).
See discussion of important constraints on
Timer callbacks.
Note
Memory can’t be allocated inside irq handlers (an interrupt) and so
exceptions raised within a handler don’t give much information.
See
micropython.alloc_emergency_exception_buf()
for how to get around this
limitation.
If you are using a WiPy board please refer to machine.TimerWiPy
instead of this class.
Constructors
- class
machine.
Timer
(id, ...)
- Construct a new timer object of the given id.
Id of -1 constructs a
virtual timer (if supported by a board).
Methods
Timer.
init
(*, mode=Timer.PERIODIC, period=-1, callback=None)
- Initialise the timer.
Example:
tim.init(period=100) # periodic with 100ms period
tim.init(mode=Timer.ONE_SHOT, period=1000) # one shot firing after 1000ms
Keyword arguments:
mode
can be one of:
Timer.ONE_SHOT
- The timer runs once until the configured
period of the channel expires.
Timer.PERIODIC
- The timer runs periodically at the configured
frequency of the channel.
Timer.
deinit
()
- Deinitialises the timer.
Stops the timer, and disables the timer peripheral.
Constants
Timer.
ONE_SHOT
-
Timer.
PERIODIC
- Timer operating mode.
class WDT - watchdog timer
The WDT is used to restart the system when the application crashes and ends
up into a non recoverable state.
Once started it cannot be stopped or
reconfigured in any way.
After enabling, the application must "feed" the
watchdog periodically to prevent it from expiring and resetting the system.
Example usage:
from machine import WDT
wdt = WDT(timeout=2000) # enable it with a timeout of 2s
wdt.feed()
Availability of this class: pyboard, WiPy.
Constructors
- class
machine.
WDT
(id=0, timeout=5000)
- Create a WDT object and start it.
The timeout must be given in seconds and
the minimum value that is accepted is 1 second.
Once it is running the timeout
cannot be changed and the WDT cannot be stopped either.
Methods
wdt.
feed
()
- Feed the WDT to prevent it from resetting the system.
The application
should place this call in a sensible place ensuring that the WDT is
only fed after verifying that everything is functioning correctly.
class SD - secure digital memory card (cc3200 port only)
Warning
This is a non-standard class and is only available on the cc3200 port.
The SD card class allows to configure and enable the memory card
module of the WiPy and automatically mount it as /sd
as part
of the file system.
There are several pin combinations that can be
used to wire the SD card socket to the WiPy and the pins used can
be specified in the constructor.
Please check the pinout and alternate functions
table. for
more info regarding the pins which can be remapped to be used with a SD card.
Example usage:
from machine import SD
import os
# clk cmd and dat0 pins must be passed along with
# their respective alternate functions
sd = machine.SD(pins=('GP10', 'GP11', 'GP15'))
os.mount(sd, '/sd')
# do normal file operations
Constructors
- class
machine.
SD
(id, ...)
- Create a SD card object.
See
init()
for parameters if initialization.
Methods
SD.
init
(id=0, pins=('GP10', 'GP11', 'GP15'))
- Enable the SD card.
In order to initialize the card, give it a 3-tuple:
(clk_pin, cmd_pin, dat0_pin)
.
SD.
deinit
()
- Disable the SD card.
class SDCard - secure digital memory card
SD cards are one of the most common small form factor removable storage media.
SD cards come in a variety of sizes and physical form factors.
MMC cards are
similar removable storage devices while eMMC devices are electrically similar
storage devices designed to be embedded into other systems.
All three form
share a common protocol for communication with their host system and high-level
support looks the same for them all.
As such in MicroPython they are implemented
in a single class called machine.SDCard
.
Both SD and MMC interfaces support being accessed with a variety of bus widths.
When being accessed with a 1-bit wide interface they can be accessed using the
SPI protocol.
Different MicroPython hardware platforms support different widths
and pin configurations but for most platforms there is a standard configuration
for any given hardware.
In general constructing an SDCard
object with without
passing any parameters will initialise the interface to the default card slot
for the current hardware.
The arguments listed below represent the common
arguments that might need to be set in order to use either a non-standard slot
or a non-standard pin assignment.
The exact subset of arguments supported will
vary from platform to platform.
- class
machine.
SDCard
(slot=1, width=1, cd=None, wp=None, sck=None, miso=None, mosi=None, cs=None)
- This class provides access to SD or MMC storage cards using either
a dedicated SD/MMC interface hardware or through an SPI channel.
The class implements the block protocol defined by
uos.AbstractBlockDev
.
This allows the mounting of an SD card to be as simple as:
uos.mount(machine.SDCard(), "/sd")
The constructor takes the following parameters:
- slot selects which of the available interfaces to use.
Leaving this
unset will select the default interface.
- width selects the bus width for the SD/MMC interface.
- cd can be used to specify a card-detect pin.
- wp can be used to specify a write-protect pin.
- sck can be used to specify an SPI clock pin.
- miso can be used to specify an SPI miso pin.
- mosi can be used to specify an SPI mosi pin.
- cs can be used to specify an SPI chip select pin.
-- Implementation-specific details
Different implementations of the SDCard
class on different hardware support
varying subsets of the options above.
..
PyBoard
The standard PyBoard has just one slot.
No arguments are necessary or supported.
..
ESP32
The ESP32 provides two channels of SD/MMC hardware and also supports
access to SD Cards through either of the two SPI ports that are
generally available to the user.
As a result the slot argument can
take a value between 0 and 3, inclusive.
Slots 0 and 1 use the
built-in SD/MMC hardware while slots 2 and 3 use the SPI ports.
Slot 0
supports 1, 4 or 8-bit wide access while slot 1 supports 1 or 4-bit
access; the SPI slots only support 1-bit access.
Note
Slot 0 is used to communicate with on-board flash memory
on most ESP32 modules and so will be unavailable to the
user.
Note
Most ESP32 modules that provide an SD card slot using the
dedicated hardware only wire up 1 data pin, so the default
value for width is 1.
The pins used by the dedicated SD/MMC hardware are fixed.
The pins
used by the SPI hardware can be reassigned.
Note
If any of the SPI signals are remapped then all of the SPI
signals will pass through a GPIO multiplexer unit which
can limit the performance of high frequency signals.
Since
the normal operating speed for SD cards is 40MHz this can
cause problems on some cards.
The default (and preferred) pin assignment are as follows:
Slot |
0 |
1 |
2 |
3 |
Signal |
Pin |
Pin |
Pin |
Pin |
sck |
6 |
14 |
18 |
14 |
cmd |
11 |
15 |
|
|
cs |
|
|
5 |
15 |
miso |
|
|
19 |
12 |
mosi |
|
|
23 |
13 |
D0 |
7 |
2 |
|
|
D1 |
8 |
4 |
|
|
D2 |
9 |
12 |
|
|
D3 |
10 |
13 |
|
|
D4 |
16 |
|
|
|
D5 |
17 |
|
|
|
D6 |
5 |
|
|
|
D7 |
18 |
|
|
|
..
cc3200
You can set the pins used for SPI access by passing a tuple as the
pins argument.
Note: The current cc3200 SD card implementation names the this class
machine.SD
rather than machine.SDCard
.
Quick reference for the ESP32
The Espressif ESP32 Development Board (image attribution: Adafruit).
Below is a quick reference for ESP32-based boards.
If it is your first time
working with this board it may be useful to get an overview of the microcontroller:
General information about the ESP32 port
Getting started with MicroPython on the ESP32
-- Installing MicroPython
See the corresponding section of tutorial: Getting started with MicroPython on the ESP32.
It also includes
a troubleshooting subsection.
-- General board control
The MicroPython REPL is on UART0 (GPIO1=TX, GPIO3=RX) at baudrate 115200.
Tab-completion is useful to find out what methods an object has.
Paste mode (ctrl-E) is useful to paste a large slab of Python code into
the REPL.
The machine
module:
import machine
machine.freq() # get the current frequency of the CPU
machine.freq(240000000) # set the CPU frequency to 240 MHz
The esp
module:
import esp
esp.osdebug(None) # turn off vendor O/S debugging messages
esp.osdebug(0) # redirect vendor O/S debugging messages to UART(0)
# low level methods to interact with flash storage
esp.flash_size()
esp.flash_user_start()
esp.flash_erase(sector_no)
esp.flash_write(byte_offset, buffer)
esp.flash_read(byte_offset, buffer)
The esp32
module:
import esp32
esp32.hall_sensor() # read the internal hall sensor
esp32.raw_temperature() # read the internal temperature of the MCU, in Farenheit
esp32.ULP() # access to the Ultra-Low-Power Co-processor
Note that the temperature sensor in the ESP32 will typically read higher than
ambient due to the IC getting warm while it runs.
This effect can be minimised
by reading the temperature sensor immediately after waking up from sleep.
-- Networking
The network
module:
import network
wlan = network.WLAN(network.STA_IF) # create station interface
wlan.active(True) # activate the interface
wlan.scan() # scan for access points
wlan.isconnected() # check if the station is connected to an AP
wlan.connect('essid', 'password') # connect to an AP
wlan.config('mac') # get the interface's MAC address
wlan.ifconfig() # get the interface's IP/netmask/gw/DNS addresses
ap = network.WLAN(network.AP_IF) # create access-point interface
ap.config(essid='ESP-AP') # set the ESSID of the access point
ap.config(max_clients=10) # set how many clients can connect to the network
ap.active(True) # activate the interface
A useful function for connecting to your local WiFi network is:
def do_connect():
import network
wlan = network.WLAN(network.STA_IF)
wlan.active(True)
if not wlan.isconnected():
print('connecting to network...')
wlan.connect('essid', 'password')
while not wlan.isconnected():
pass
print('network config:', wlan.ifconfig())
Once the network is established the socket
module can be used
to create and use TCP/UDP sockets as usual, and the urequests
module for
convenient HTTP requests.
-- Delay and timing
Use the time
module:
import time
time.sleep(1) # sleep for 1 second
time.sleep_ms(500) # sleep for 500 milliseconds
time.sleep_us(10) # sleep for 10 microseconds
start = time.ticks_ms() # get millisecond counter
delta = time.ticks_diff(time.ticks_ms(), start) # compute time difference
-- Timers
Virtual (RTOS-based) timers are supported.
Use the machine.Timer class
with timer ID of -1:
from machine import Timer
tim = Timer(-1)
tim.init(period=5000, mode=Timer.ONE_SHOT, callback=lambda t:print(1))
tim.init(period=2000, mode=Timer.PERIODIC, callback=lambda t:print(2))
The period is in milliseconds.
-- Pins and GPIO
Use the machine.Pin class:
from machine import Pin
p0 = Pin(0, Pin.OUT) # create output pin on GPIO0
p0.on() # set pin to "on" (high) level
p0.off() # set pin to "off" (low) level
p0.value(1) # set pin to on/high
p2 = Pin(2, Pin.IN) # create input pin on GPIO2
print(p2.value()) # get value, 0 or 1
p4 = Pin(4, Pin.IN, Pin.PULL_UP) # enable internal pull-up resistor
p5 = Pin(5, Pin.OUT, value=1) # set pin high on creation
Available Pins are from the following ranges (inclusive): 0-19, 21-23, 25-27, 32-39.
These correspond to the actual GPIO pin numbers of ESP32 chip.
Note that many
end-user boards use their own adhoc pin numbering (marked e.g.
D0, D1, ...).
For mapping between board logical pins and physical chip pins consult your board
documentation.
Notes:
Pins 1 and 3 are REPL UART TX and RX respectively
Pins 6, 7, 8, 11, 16, and 17 are used for connecting the embedded flash,
and are not recommended for other uses
Pins 34-39 are input only, and also do not have internal pull-up resistors
The pull value of some pins can be set to Pin.PULL_HOLD
to reduce power
consumption during deepsleep.
-- PWM (pulse width modulation)
PWM can be enabled on all output-enabled pins.
The base frequency can
range from 1Hz to 40MHz but there is a tradeoff; as the base frequency
increases the duty resolution decreases.
See
LED Control
for more details.
Use the machine.PWM
class:
from machine import Pin, PWM
pwm0 = PWM(Pin(0)) # create PWM object from a pin
pwm0.freq() # get current frequency
pwm0.freq(1000) # set frequency
pwm0.duty() # get current duty cycle
pwm0.duty(200) # set duty cycle
pwm0.deinit() # turn off PWM on the pin
pwm2 = PWM(Pin(2), freq=20000, duty=512) # create and configure in one go
-- ADC (analog to digital conversion)
On the ESP32 ADC functionality is available on Pins 32-39.
Note that, when
using the default configuration, input voltages on the ADC pin must be between
0.0v and 1.0v (anything above 1.0v will just read as 4095).
Attenuation must
be applied in order to increase this usable voltage range.
Use the machine.ADC class:
from machine import ADC
adc = ADC(Pin(32)) # create ADC object on ADC pin
adc.read() # read value, 0-4095 across voltage range 0.0v - 1.0v
adc.atten(ADC.ATTN_11DB) # set 11dB input attenuation (voltage range roughly 0.0v - 3.6v)
adc.width(ADC.WIDTH_9BIT) # set 9 bit return values (returned range 0-511)
adc.read() # read value using the newly configured attenuation and width
ESP32 specific ADC class method reference:
ADC.
atten
(attenuation)
- This method allows for the setting of the amount of attenuation on the
input of the ADC.
This allows for a wider possible input voltage range,
at the cost of accuracy (the same number of bits now represents a wider
range).
The possible attenuation options are:
ADC.ATTN_0DB
: 0dB attenuation, gives a maximum input voltage
of 1.00v - this is the default configuration
ADC.ATTN_2_5DB
: 2.5dB attenuation, gives a maximum input voltage
of approximately 1.34v
ADC.ATTN_6DB
: 6dB attenuation, gives a maximum input voltage
of approximately 2.00v
ADC.ATTN_11DB
: 11dB attenuation, gives a maximum input voltage
of approximately 3.6v
Warning
Despite 11dB attenuation allowing for up to a 3.6v range, note that the
absolute maximum voltage rating for the input pins is 3.6v, and so going
near this boundary may be damaging to the IC!
ADC.
width
(width)
- This method allows for the setting of the number of bits to be utilised
and returned during ADC reads.
Possible width options are:
ADC.WIDTH_9BIT
: 9 bit data
ADC.WIDTH_10BIT
: 10 bit data
ADC.WIDTH_11BIT
: 11 bit data
ADC.WIDTH_12BIT
: 12 bit data - this is the default configuration
-- Software SPI bus
There are two SPI drivers.
One is implemented in software (bit-banging)
and works on all pins, and is accessed via the machine.SPI
class:
from machine import Pin, SPI
# construct an SPI bus on the given pins
# polarity is the idle state of SCK
# phase=0 means sample on the first edge of SCK, phase=1 means the second
spi = SPI(baudrate=100000, polarity=1, phase=0, sck=Pin(0), mosi=Pin(2), miso=Pin(4))
spi.init(baudrate=200000) # set the baudrate
spi.read(10) # read 10 bytes on MISO
spi.read(10, 0xff) # read 10 bytes while outputting 0xff on MOSI
buf = bytearray(50) # create a buffer
spi.readinto(buf) # read into the given buffer (reads 50 bytes in this case)
spi.readinto(buf, 0xff) # read into the given buffer and output 0xff on MOSI
spi.write(b'12345') # write 5 bytes on MOSI
buf = bytearray(4) # create a buffer
spi.write_readinto(b'1234', buf) # write to MOSI and read from MISO into the buffer
spi.write_readinto(buf, buf) # write buf to MOSI and read MISO back into buf
Warning
Currently all of sck
, mosi
and miso
must be specified when
initialising Software SPI.
-- Hardware SPI bus
There are two hardware SPI channels that allow faster transmission
rates (up to 80Mhz).
These may be used on any IO pins that support the
required direction and are otherwise unused (see Pins and GPIO)
but if they are not configured to their default pins then they need to
pass through an extra layer of GPIO multiplexing, which can impact
their reliability at high speeds.
Hardware SPI channels are limited
to 40MHz when used on pins other than the default ones listed below.
|
HSPI (id=1) |
VSPI (id=2) |
sck |
14 |
18 |
mosi |
13 |
23 |
miso |
12 |
19 |
Hardware SPI has the same methods as Software SPI above:
from machine import Pin, SPI
hspi = SPI(1, 10000000, sck=Pin(14), mosi=Pin(13), miso=Pin(12))
vspi = SPI(2, baudrate=80000000, polarity=0, phase=0, bits=8, firstbit=0, sck=Pin(18), mosi=Pin(23), miso=Pin(19))
-- I2C bus
The I2C driver has both software and hardware implementations, and the two
hardware peripherals have identifiers 0 and 1.
Any available output-capable
pins can be used for SCL and SDA.
The driver is accessed via the
machine.I2C class:
from machine import Pin, I2C
# construct a software I2C bus
i2c = I2C(scl=Pin(5), sda=Pin(4), freq=100000)
# construct a hardware I2C bus
i2c = I2C(0)
i2c = I2C(1, scl=Pin(5), sda=Pin(4), freq=400000)
i2c.scan() # scan for slave devices
i2c.readfrom(0x3a, 4) # read 4 bytes from slave device with address 0x3a
i2c.writeto(0x3a, '12') # write '12' to slave device with address 0x3a
buf = bytearray(10) # create a buffer with 10 bytes
i2c.writeto(0x3a, buf) # write the given buffer to the slave
-- Real time clock (RTC)
See machine.RTC
from machine import RTC
rtc = RTC()
rtc.datetime((2017, 8, 23, 1, 12, 48, 0, 0)) # set a specific date and time
rtc.datetime() # get date and time
-- Deep-sleep mode
The following code can be used to sleep, wake and check the reset cause:
import machine
# check if the device woke from a deep sleep
if machine.reset_cause() == machine.DEEPSLEEP_RESET:
print('woke from a deep sleep')
# put the device to sleep for 10 seconds
machine.deepsleep(10000)
Notes:
Calling deepsleep()
without an argument will put the device to sleep
indefinitely
A software reset does not change the reset cause
There may be some leakage current flowing through enabled internal pullups.
To further reduce power consumption it is possible to disable the internal pullups:
p1 = Pin(4, Pin.IN, Pin.PULL_HOLD)
After leaving deepsleep it may be necessary to un-hold the pin explicitly (e.g.
if
it is an output pin) via:
p1 = Pin(4, Pin.OUT, None)
-- RMT
The RMT is ESP32-specific and allows generation of accurate digital pulses with
12.5ns resolution.
See esp32.RMT for details.
Usage is:
import esp32
from machine import Pin
r = esp32.RMT(0, pin=Pin(18), clock_div=8)
r # RMT(channel=0, pin=18, source_freq=80000000, clock_div=8)
# The channel resolution is 100ns (1/(source_freq/clock_div)).
r.write_pulses((1, 20, 2, 40), start=0) # Send 0 for 100ns, 1 for 2000ns, 0 for 200ns, 1 for 4000ns
-- OneWire driver
The OneWire driver is implemented in software and works on all pins:
from machine import Pin
import onewire
ow = onewire.OneWire(Pin(12)) # create a OneWire bus on GPIO12
ow.scan() # return a list of devices on the bus
ow.reset() # reset the bus
ow.readbyte() # read a byte
ow.writebyte(0x12) # write a byte on the bus
ow.write('123') # write bytes on the bus
ow.select_rom(b'12345678') # select a specific device by its ROM code
There is a specific driver for DS18S20 and DS18B20 devices:
import time, ds18x20
ds = ds18x20.DS18X20(ow)
roms = ds.scan()
ds.convert_temp()
time.sleep_ms(750)
for rom in roms:
print(ds.read_temp(rom))
Be sure to put a 4.7k pull-up resistor on the data line.
Note that
the convert_temp()
method must be called each time you want to
sample the temperature.
-- NeoPixel driver
Use the neopixel
module:
from machine import Pin
from neopixel import NeoPixel
pin = Pin(0, Pin.OUT) # set GPIO0 to output to drive NeoPixels
np = NeoPixel(pin, 8) # create NeoPixel driver on GPIO0 for 8 pixels
np[0] = (255, 255, 255) # set the first pixel to white
np.write() # write data to all pixels
r, g, b = np[0] # get first pixel colour
For low-level driving of a NeoPixel:
import esp
esp.neopixel_write(pin, grb_buf, is800khz)
Warning
By default NeoPixel
is configured to control the more popular 800kHz
units.
It is possible to use alternative timing to control other (typically
400kHz) devices by passing timing=0
when constructing the
NeoPixel
object.
-- Capacitive touch
Use the TouchPad
class in the machine
module:
from machine import TouchPad, Pin
t = TouchPad(Pin(14))
t.read() # Returns a smaller number when touched
TouchPad.read
returns a value relative to the capacitive variation.
Small numbers (typically in
the tens) are common when a pin is touched, larger numbers (above one thousand) when
no touch is present.
However the values are relative and can vary depending on the board
and surrounding composition so some calibration may be required.
There are ten capacitive touch-enabled pins that can be used on the ESP32: 0, 2, 4, 12, 13
14, 15, 27, 32, 33.
Trying to assign to any other pins will result in a ValueError
.
Note that TouchPads can be used to wake an ESP32 from sleep:
import machine
from machine import TouchPad, Pin
import esp32
t = TouchPad(Pin(14))
t.config(500) # configure the threshold at which the pin is considered touched
esp32.wake_on_touch(True)
machine.lightsleep() # put the MCU to sleep until a touchpad is touched
For more details on touchpads refer to Espressif Touch Sensor.
-- DHT driver
The DHT driver is implemented in software and works on all pins:
import dht
import machine
d = dht.DHT11(machine.Pin(4))
d.measure()
d.temperature() # eg.
23 (°C)
d.humidity() # eg.
41 (% RH)
d = dht.DHT22(machine.Pin(4))
d.measure()
d.temperature() # eg.
23.6 (°C)
d.humidity() # eg.
41.3 (% RH)
-- WebREPL (web browser interactive prompt)
WebREPL (REPL over WebSockets, accessible via a web browser) is an
experimental feature available in ESP32 port.
Download web client
from https://github.com/micropython/webrepl (hosted version available
at http://micropython.org/webrepl), and configure it by executing:
import webrepl_setup
and following on-screen instructions.
After reboot, it will be available
for connection.
If you disabled automatic start-up on boot, you may
run configured daemon on demand using:
import webrepl
webrepl.start()
# or, start with a specific password
webrepl.start(password='mypass')
The WebREPL daemon listens on all active interfaces, which can be STA or
AP.
This allows you to connect to the ESP32 via a router (the STA
interface) or directly when connected to its access point.
In addition to terminal/command prompt access, WebREPL also has provision
for file transfer (both upload and download).
The web client has buttons for
the corresponding functions, or you can use the command-line client
webrepl_cli.py
from the repository above.
See the MicroPython forum for other community-supported alternatives
to transfer files to an ESP32 board.